#pragma once

#include "buffer.h"
#include "callbacks.h"
#include "channel.h"
#include "event_loop.h"
#include "inet_address.h"
#include "noncopyable.h"
#include "socket.h"
#include "timestamp.h"

#include <atomic>
#include <memory>
#include <string>

class Channel;
class EventLoop;
class Socket;

/*
    TcpSerber => Acceptor => 有一个新用户连接，通过accept函数拿到connfd
    => TcpConnection 通过设置回调=> Channel => Channel 的回调操作
*/

class TcpConnection : noncopyable, public std::enable_shared_from_this<TcpConnection> {
  public:
    TcpConnection(EventLoop *loop, const std::string &name, int sockfd,
                  const InetAddress &local_addr, const InetAddress &peer_addr);
    ~TcpConnection();

    EventLoop *get_loop() const { return loop_; }
    const std::string &name() const { return name_; }
    const InetAddress &local_address() const { return local_addr_; }
    const InetAddress &peer_address_() const { return peer_addr_; }

    bool connected() const { return state_ == kConnected; }

    void set_connection_callback(const ConnectionCallback &cb) { connection_callback_ = cb; }
    void set_message_callback(const MessageCallback &cb) { message_callback_ = cb; }
    void set_write_complete_callback(const WriteCompleteCallback &cb) {
        write_complete_callback_ = cb;
    }
    void set_high_water_mark_callback(const HighWaterMarkCallback &cb, size_t high_water_mark) {
        high_water_mark_callback_ = cb;
        high_water_mark_ = high_water_mark;
    }
    void set_close_callback(const CloseCallback &cb) { close_callback_ = cb; }

    // 连接建立
    void connect_established();
    // 连接销毁
    void connect_destroyed();

    // 发送数据
    void send(const std::string &buf);
    // 关闭连接
    void shutdown();

  private:
    enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };
    void set_state(StateE state) { state_ = state; }
    void handle_read(Timestamp receive_time);
    void handle_write();
    void handle_close();
    void handle_error();

    void send_in_loop(const void *message, size_t len);
    void shutdown_in_loop();

    EventLoop *loop_; // 这里绝对不是base_loop,因为tcp_connection都是sub_loop里面管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;

    // 和acceptor很像 accepto是main_loop ，这个是sub_loop
    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    const InetAddress local_addr_;
    const InetAddress peer_addr_;

    ConnectionCallback connection_callback_;        // 有新连接的回调
    MessageCallback message_callback_;              // 有读写消息的回调
    WriteCompleteCallback write_complete_callback_; // 消息发送完成后的回调
    HighWaterMarkCallback high_water_mark_callback_;
    CloseCallback close_callback_;
    size_t high_water_mark_;

    Buffer input_buffer_;
    Buffer output_buffer_;
};